package com.superluo.textbannerlibrary;

import com.superluo.textbannerlibrary.utils.AttrUtils;
import com.superluo.textbannerlibrary.utils.DensityUtil;
import com.superluo.textbannerlibrary.utils.DisplayUtils;
import ohos.agp.animation.AnimatorProperty;
import ohos.agp.components.AttrSet;
import ohos.agp.components.Component;
import ohos.agp.components.ComponentContainer;
import ohos.agp.components.DirectionalLayout;
import ohos.agp.components.PageFlipper;
import ohos.agp.components.Text;
import ohos.agp.components.element.PixelMapElement;
import ohos.agp.text.Font;
import ohos.agp.utils.Color;
import ohos.agp.utils.TextAlignment;
import ohos.agp.window.service.Display;
import ohos.agp.window.service.DisplayAttributes;
import ohos.agp.window.service.DisplayManager;
import ohos.app.Context;
import ohos.eventhandler.EventHandler;
import ohos.eventhandler.EventRunner;

import java.util.List;
import java.util.Optional;

import static ohos.agp.utils.LayoutAlignment.*;

/**
 * @author luoweichao
 * @描述 文字自动轮播（跑马灯）
 * @email superluo666@gmail.com
 * @date 2018/3/28/028 21:21
 */
public class TextBannerView extends ComponentContainer {
    private PageFlipper mViewFlipper;
    private int mInterval = 3000;
    /**
     * 文字切换时间间隔,默认3s
     */
    private boolean isSingleLine = false;
    /**
     * 文字是否为单行,默认false
     */
    private int mTextColor = 0xff000000;
    /**
     * 设置文字颜色,默认黑色
     */
    private int mTextSize = 16;
    /**
     * 设置文字尺寸,默认16px
     */
    private int mGravity = TextAlignment.LEFT | TextAlignment.VERTICAL_CENTER;
    /**
     * 文字显示位置,默认左边居中
     */
    private static final String GRAVITY_LEFT = "left";
    private static final String GRAVITY_CENTER = "center";
    private static final String GRAVITY_RIGHT = "right";
    private boolean hasSetDirection = false;
    private String direction = DIRECTION_BOTTOM_TO_TOP;
    private static final String DIRECTION_BOTTOM_TO_TOP = "bottom_to_top";
    private static final String DIRECTION_TOP_TO_BOTTOM = "top_to_bottom";
    private static final String DIRECTION_RIGHT_TO_LEFT = "right_to_left";
    private static final String DIRECTION_LEFT_TO_RIGHT = "left_to_right";
    private String inAnimResId = "anim_right_in";
    private String outAnimResId = "anim_left_out";
    private boolean hasSetAnimDuration = false;
    private int animDuration = 1500;
    /**
     * 默认1.5s
     */
    private int mFlags = -1;
    /**
     * 文字划线
     */
    private static final int STRIKE = 0;
    private static final int UNDER_LINE = 1;
    private static final String TYPE_NORMAL = "normal";
    private static final String TYPE_BOLD = "bold";
    private static final String TYPE_ITALIC = "italic";
    private static final String TYPE_ITALIC_BOLD = "italic_bold";
    private List<String> mDatas;
    private ITextBannerItemClickListener mListener;
    private boolean isStarted;
    private boolean isDetachedFromWindow;
    private EventHandler eventHandler;
    private String mTypeface;

    public TextBannerView(Context context) {
        this(context, null);
    }

    public TextBannerView(Context context, AttrSet attrSet) {
        super(context, attrSet);
        eventHandler = new EventHandler(EventRunner.getMainEventRunner());
        init(context, attrSet, 0);
    }


    /**
     * Init *
     *
     * @param context      context
     * @param attrSet      attr set
     * @param defStyleAttr def style attr
     */
    private void init(Context context, AttrSet attrSet, int defStyleAttr) {
        mInterval = AttrUtils.getIntFromAttr(attrSet, "setInterval", mInterval);//文字切换时间间隔
        isSingleLine = AttrUtils.getBooleanFromAttr(attrSet, "setSingleLine", false);//文字是否为单行
        mTextColor = AttrUtils.getColorFromAttr(attrSet, "setTextColor", mTextColor);//设置文字颜色
        mTextSize = (int) AttrUtils.getDimensionFromAttr(attrSet, "setTextSize", mTextSize);
        mTextSize = DisplayUtils.px2sp(mTextSize);
        String gravityType = AttrUtils.getStringFromAttr(attrSet, "setGravity", "left");//显示位置
        switch (gravityType) {
            case GRAVITY_LEFT:
                mGravity = TextAlignment.LEFT | TextAlignment.VERTICAL_CENTER;
                break;
            case GRAVITY_CENTER:
                mGravity = TextAlignment.CENTER;
                break;
            case GRAVITY_RIGHT:
                mGravity = TextAlignment.RIGHT | TextAlignment.VERTICAL_CENTER;
                break;
        }
        hasSetAnimDuration = AttrUtils.getBooleanFromAttr(attrSet, "setGravity", false);
        animDuration = AttrUtils.getIntFromAttr(attrSet, "setAnimDuration", animDuration);//动画时间
        hasSetDirection = AttrUtils.getBooleanFromAttr(attrSet, "setDirection", true);
        direction = AttrUtils.getStringFromAttr(attrSet, "setDirection", "right_to_left");//方向
        if (hasSetDirection) {
            switch (direction) {
                case DIRECTION_BOTTOM_TO_TOP:
                    inAnimResId = "anim_bottom_in";
                    outAnimResId = "anim_top_out";
                    break;
                case DIRECTION_TOP_TO_BOTTOM:
                    inAnimResId = "anim_top_in";
                    outAnimResId = "anim_bottom_out";
                    break;
                case DIRECTION_RIGHT_TO_LEFT:
                    inAnimResId = "anim_right_in";
                    outAnimResId = "anim_left_out";
                    break;
                case DIRECTION_LEFT_TO_RIGHT:
                    inAnimResId = "anim_left_in";
                    outAnimResId = "anim_right_out";
                    break;
            }
        } else {
            inAnimResId = "anim_right_in";
            outAnimResId = "anim_left_out";
        }

        //字体样式
        mTypeface = AttrUtils.getStringFromAttr(attrSet, "setTypeface", TYPE_NORMAL);
        switch (mTypeface) {
            case TYPE_BOLD:
                mTypeface = TYPE_BOLD;
                break;
            case TYPE_ITALIC:
                mTypeface = TYPE_ITALIC;
                break;
            case TYPE_ITALIC_BOLD:
                mTypeface = TYPE_ITALIC_BOLD;
                break;
            default:
                break;
        }


        mViewFlipper = new PageFlipper(getContext());
        mViewFlipper.setLayoutConfig(new LayoutConfig(LayoutConfig.MATCH_PARENT, LayoutConfig.MATCH_PARENT));
        addComponent(mViewFlipper);
        // startViewAnimator();
        //设置点击事件
        setClickedListener(new ClickedListener() {
            @Override
            public void onClick(Component component) {
                int position = mViewFlipper.getCurrentIndex() == -1 ? 0 : mViewFlipper.getCurrentIndex();//当前显示的子视图的索引位置
                if (mListener != null) {
                    mListener.onItemClick(mDatas.get(position), position);
                }
            }
        });

    }

    /**
     * 暂停动画
     */
    public void stopViewAnimator() {
        if (isStarted) {
            eventHandler.removeTask(mRunnable);
            isStarted = false;
        }
    }

    /**
     * 开始动画
     */
    public void startViewAnimator() {
        if (!isStarted) {
            if (!isDetachedFromWindow) {
                isStarted = true;
                eventHandler.postTask(mRunnable, mInterval);
            }
        }
    }

    /**
     * 设置延时间隔
     */
    private AnimRunnable mRunnable = new AnimRunnable();

    private class AnimRunnable implements Runnable {
        @Override
        public void run() {
            if (isStarted) {
                if (mViewFlipper.getCurrentIndex() == -1) {
                    mViewFlipper.setCurrentIndex(0);
                }
                setInAndOutAnimation(inAnimResId, outAnimResId);
                if (mViewFlipper.getCurrentIndex() == mViewFlipper.getChildCount() - 1) {
                    mViewFlipper.setCurrentIndex(0);
                } else {
                    mViewFlipper.showNext();//手动显示下一个子view。
                }
                eventHandler.postTask(this, mInterval + animDuration);
            } else {
                stopViewAnimator();
            }

        }
    }


    /**
     * Sets in and out animation *
     *
     * @param inAnimResId  in anim res id
     * @param outAnimResId out anim res id
     */
    private void setInAndOutAnimation(String inAnimResId, String outAnimResId) {
        AnimatorProperty animator = createAnimatorProperty();
        // Animation inAnim = AnimationUtils.loadAnimation(getContext(), inAnimResId);
        animator.setDuration(animDuration);
        if (inAnimResId.equals("anim_bottom_in")) {
            animator.moveFromY(getHeight()).moveToY(0);
        } else if (inAnimResId.equals("anim_top_in")) {
            animator.moveFromY(-getHeight()).moveToY(0);
        } else if (inAnimResId.equals("anim_right_in")) {
            animator.moveFromX(getWidth()).moveToX(0);
        } else if (inAnimResId.equals("anim_left_in")) {
            animator.moveFromX(-getWidth()).moveToX(0);
        }
        mViewFlipper.setIncomingAnimation(animator);
        AnimatorProperty outAnim = createAnimatorProperty();
        outAnim.setDuration(animDuration);
        if (outAnimResId.equals("anim_top_out")) {
            outAnim.moveFromY(0).moveToY(-getHeight());
        } else if (outAnimResId.equals("anim_bottom_out")) {
            outAnim.moveFromY(0).moveToY(getHeight());
        } else if (outAnimResId.equals("anim_left_out")) {
            outAnim.moveFromX(0).moveToX(-getWidth());
        } else if (outAnimResId.equals("anim_right_out")) {
            outAnim.moveFromX(0).moveToX(getWidth());
        }
        mViewFlipper.setOutgoingAnimation(outAnim);
    }

    /**
     * Sets datas *
     *
     * @param datas datas
     */
    public void setDatas(List<String> datas) {
        this.mDatas = datas;
        if (DisplayUtils.notEmpty(mDatas)) {
            mViewFlipper.removeAllComponents();
            for (int i = 0; i < mDatas.size(); i++) {
                Text textView = new Text(getContext());
                setTextView(textView, i);
                LayoutConfig layoutConfig = textView.getLayoutConfig();
                layoutConfig.width = LayoutConfig.MATCH_PARENT;
                textView.setLayoutConfig(layoutConfig);
                textView.setHeight(DensityUtil.dp2px(getContext(), 38));
                textView.setMultipleLine(true);
                switch (mTypeface) {
                    case TYPE_BOLD:
                        Font.Builder fontBoldBuilder = new Font.Builder("");
                        fontBoldBuilder.setWeight(1000);
                        Font font = fontBoldBuilder.build();
                        textView.setFont(Font.DEFAULT_BOLD);
                        break;
                    case TYPE_ITALIC:
                        Font.Builder fontItalicBuilder = new Font.Builder("");
                        fontItalicBuilder.makeItalic(true);
                        Font fontItalic = fontItalicBuilder.build();
                        textView.setFont(fontItalic);
                        break;
                    case TYPE_ITALIC_BOLD:
                        Font.Builder fontItalicBoldBuilder = new Font.Builder("");
                        fontItalicBoldBuilder.makeItalic(true);
                        fontItalicBoldBuilder.setWeight(1000);
                        Font fontItalicBold = fontItalicBoldBuilder.build();
                        textView.setFont(fontItalicBold);
                        break;
                    default:
                        break;
                }
                mViewFlipper.addComponent(textView, i);//添加子view,并标识子view位置
            }
        }

    }

    /**
     * 设置数据集合伴随drawable-icon
     *
     * @param datas     数据
     * @param drawable  图标
     * @param size      图标尺寸
     * @param direction 图标位于文字方位
     */
    public void setDatasWithDrawableIcon(List<String> datas, PixelMapElement drawable, int size, int direction) {
        this.mDatas = datas;
        if (DisplayUtils.isEmpty(mDatas)) {
            return;
        }
        mViewFlipper.removeAllComponents();
        for (int i = 0; i < mDatas.size(); i++) {
            Text textView = new Text(getContext());
            setTextView(textView, i);
            textView.setAroundElementsPadding(8);
            Optional<Display>
                    display = DisplayManager.getInstance().getDefaultDisplay(this.getContext());
            DisplayAttributes displayAttributes = display.get().getAttributes();
            float scale = displayAttributes.scalDensity;// 屏幕密度 ;
            int muchDp = (int) (size * scale + 0.5f);
            //drawable.setBounds(0, 0, muchDp, muchDp);
            if (direction == LEFT) {
                textView.setAroundElements(drawable, null, null, null);//左边
            } else if (direction == TOP) {
                textView.setAroundElements(null, drawable, null, null);//顶部
            } else if (direction == RIGHT) {
                textView.setAroundElements(null, null, drawable, null);//右边
            } else if (direction == BOTTOM) {
                textView.setAroundElements(null, null, null, drawable);//底部
            }
            DirectionalLayout linearLayout = new DirectionalLayout(getContext());
            linearLayout.setOrientation(DirectionalLayout.HORIZONTAL);//水平方向
            LayoutConfig param = linearLayout.getLayoutConfig();
            param.width = LayoutConfig.MATCH_PARENT;
            linearLayout.setLayoutConfig(param);
            linearLayout.setHeight(DensityUtil.dp2px(getContext(), 38));
            textView.setHeight(DensityUtil.dp2px(getContext(), 38));
            linearLayout.addComponent(textView);
            linearLayout.setAlignment(mGravity);//子view显示位置跟随TextView
            mViewFlipper.addComponent(linearLayout, i);//添加子view,并标识子view位置
        }
    }


    /**
     * Sets text view *
     *
     * @param textView text view
     * @param position position
     */
    private void setTextView(Text textView, int position) {
        textView.setText(mDatas.get(position));
        //任意设置你的文字样式，在这里
        textView.setMultipleLine(isSingleLine);
        textView.setTextColor(new Color(mTextColor));
        textView.setTextSize(mTextSize);
        textView.setTextAlignment(mGravity);


    }

    /**
     * Sets item on click listener *
     *
     * @param listener listener
     */
    public void setItemOnClickListener(ITextBannerItemClickListener listener) {
        this.mListener = listener;
    }

}
